package com.holly.unit.gen.starter.config.builder;

import cn.hutool.core.util.StrUtil;
import com.holly.unit.gen.api.config.GenCodeCfg;
import com.holly.unit.gen.api.config.GenFileCfg;
import com.holly.unit.gen.api.pojo.ColumnInfo;
import com.holly.unit.gen.api.pojo.TableInfo;
import com.holly.unit.gen.api.util.RandomUtil;
import com.holly.unit.gen.starter.config.*;
import com.holly.unit.genx.util.DatabaseExtUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 类描述: 配置汇总 传递给文件生成工具
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/1/19 16:15
 */
public class ConfigBuilder {

    private DataSourceConfig dataSourceConfig;

    private GlobalConfig globalConfig;

    private PackageConfig packageConfig;

    private StrategyConfig strategyConfig;

    private TemplateConfig templateConfig;

    private Map<String,Object> templateData;

    private TableInfo tableInfo;

    private GenFileCfg genFileCfg;

    public ConfigBuilder(){}

    public ConfigBuilder(PackageConfig packageConfig, DataSourceConfig dataSourceConfig, StrategyConfig strategyConfig,
                         TemplateConfig template, GlobalConfig globalConfig,TableInfo tableInfo) {

        // 全局配置
        this.globalConfig = Optional.ofNullable(globalConfig).orElseGet(GlobalConfig::new);
        // 模板配置
        this.templateConfig = Optional.ofNullable(template).orElseGet(TemplateConfig::new);

        this.dataSourceConfig = dataSourceConfig;
        // 策略配置
        this.strategyConfig = Optional.ofNullable(strategyConfig).orElseGet(StrategyConfig::new);

        this.packageConfig = Optional.ofNullable(packageConfig).orElseGet(PackageConfig::new);

        this.tableInfo = Optional.ofNullable(tableInfo).orElseGet(TableInfo::new);

    }

    //根据表的信息和配置文件信息生成填充数据的模板
    public Map<String, Object> init()  {
        Map<String,Object> data = new HashMap<>();
        //业务包名
        data.put("bussiPackage", GenCodeCfg.getBussiPackage());
        // 填写包名小写
        data.put("entityPackage",tableInfo.getEntityPackage());
        // 填写实体名首字母大写
        data.put("entityName",tableInfo.getEntityName());
        //前端模块名称
        data.put("vueModularName",tableInfo.getEntityName().toLowerCase());
        // 填写表名
        data.put("tableName",tableInfo.getTableName());
        //自定义主键
        data.put("primaryKeyField",GenCodeCfg.getDbTableId());

        // 默认字段必须输入个数
        if (tableInfo.getFieldRequiredNum() == null) {
            tableInfo.setFieldRequiredNum(StrUtil.isNotEmpty(GenCodeCfg.getPageFieldReqNum())?Integer.parseInt(GenCodeCfg.getPageFieldReqNum()):-1);
        }

        // 默认生成几个查询条件
        if (tableInfo.getQueryFieldNum() == null) {
            tableInfo.setQueryFieldNum(StrUtil.isNotEmpty(GenCodeCfg.getPageQueryNum())?Integer.parseInt(GenCodeCfg.getPageQueryNum()):-1);
        }

        // 默认一行显示几个字段
        if (tableInfo.getFieldNumInRow() == null) {
            tableInfo.setFieldNumInRow(Integer.parseInt(GenCodeCfg.getFieldInRowNum()));
        }
        // 主参数设置
        data.put("tableVo",tableInfo);

        try {
            List<ColumnInfo> columnInfos = null;
            if (columnInfos == null || columnInfos.size() == 0) {
                // 根据表名查询表字段信息
                columnInfos = DatabaseExtUtil.findAllTableColumns(tableInfo.getTableName());
            }
            data.put("columns",columnInfos);
            List<ColumnInfo> fieldInfos = null;
            if (fieldInfos == null || fieldInfos.size() == 0) {
                // 获取表字段对应实体信息
                fieldInfos = DatabaseExtUtil.findOriginalTableColumn(tableInfo.getTableName());
            }
            data.put("originalColumns",fieldInfos);

            for (ColumnInfo columnInfo:fieldInfos) {
                if (columnInfo.getFieldName().toLowerCase().equals(GenCodeCfg.getDbTableId().toLowerCase())) {
                    data.put("primaryKeyPolicy",columnInfo.getFieldType());
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        long serialVersionUID = RandomUtil.randomLong()+RandomUtil.curMills();
        data.put("serialVersionUID",serialVersionUID);
        return data;
    }

    public DataSourceConfig getDataSourceConfig() {
        return dataSourceConfig;
    }

    public void setDataSourceConfig(DataSourceConfig dataSourceConfig) {
        this.dataSourceConfig = dataSourceConfig;
    }

    public GlobalConfig getGlobalConfig() {
        return globalConfig;
    }

    public void setGlobalConfig(GlobalConfig globalConfig) {
        this.globalConfig = globalConfig;
    }

    public PackageConfig getPackageConfig() {
        return packageConfig;
    }

    public void setPackageConfig(PackageConfig packageConfig) {
        this.packageConfig = packageConfig;
    }

    public StrategyConfig getStrategyConfig() {
        return strategyConfig;
    }

    public void setStrategyConfig(StrategyConfig strategyConfig) {
        this.strategyConfig = strategyConfig;
    }

    public TemplateConfig getTemplateConfig() {
        return templateConfig;
    }

    public void setTemplateConfig(TemplateConfig templateConfig) {
        this.templateConfig = templateConfig;
    }

    public TableInfo getTableInfo() {
        return tableInfo;
    }

    public void setTableInfo(TableInfo tableInfo) {
        this.tableInfo = tableInfo;
    }

    public Map<String, Object> getTemplateData() {
        return this.init();
    }

    public void setTemplateData(Map<String, Object> templateData) {
        this.templateData = templateData;
    }

    public GenFileCfg getGenFileCfg() {
        return genFileCfg;
    }

    public void setGenFileCfg(GenFileCfg genFileCfg) {
        this.genFileCfg = genFileCfg;
    }
}
